home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / wp / ehp10.zip / SE.C < prev    next >
C/C++ Source or Header  |  1993-06-20  |  35KB  |  831 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  se.c                                            */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - ask_replace (fragen, ob ersetzen)             */
  7. /*              - upcase (Buchstabe in Grossbuchstabe wandeln)  */
  8. /*              - instr (String in Text?)                       */
  9. /*              - find (Begriff im Text suchen)                 */
  10. /*              - str_to_num (String in Zahl wandeln)           */
  11. /*              - o_to_vals (Optionen in Werte wandeln)         */
  12. /*              - do_repfr (Latztes Suchen/Ersetzen wiederh.)   */
  13. /*              - do_find (Suche ausfuehren)                    */
  14. /*              - trag_e_ein (Ersetzungsbegriff eintragen)      */
  15. /*              - flash_word (Wort zum Blinken bringen)         */
  16. /*              - unflash_word (Wort "entblinken")              */
  17. /*              - do_replace (Ersetzen ausfuehren)              */
  18. /*                                                              */
  19. /****************************************************************/
  20.  
  21. #include "defs.h"
  22. #include <ctype.h>
  23.  
  24. extern char *fastzeichen();
  25. extern char space;
  26. extern WINDOW *status;
  27. extern int ersetzaddr;
  28.  
  29. void do_find(), do_replace();
  30.  
  31. /* *** globale Daten und Initialisierung *** */
  32. static char sbegriff[256],    /* Suchbegriff                                 */
  33.         ebegriff[256],    /* Ersetzungsbegriff                           */
  34.         optionen[256];    /* String fuer Optioneneingabe                 */
  35. int         repeatflag=FALSE, /* Ist aktueller Vorgang eine Wiederholung ?   */
  36.         last_func=F_NONE; /* Art des letzten Vorgangs (Suchen, Ersetzen) */
  37.  
  38. unsigned char upcase();
  39.  
  40. /*****************************************************************************
  41. *
  42. *  Funktion       Fragen, ob ersetzt werden soll (ask_replace)
  43. *  --------
  44. *
  45. *  Ergebnis     :
  46. *                   Typ          : int char
  47. *                   Wertebereich : (char) 0 - (char) 255
  48. *                   Bedeutung    : Eingelesenes Zeichen (upcase)
  49. *
  50. *  Beschreibung : Es wird ein Prompt im Statusfenster ausgegeben, das
  51. *                 der User durch Eingabe eines Zeichens beantworten kann.
  52. *                 Es sind nur die Zeichen j,J,n,N,a,A zugelassen. Der
  53. *                 Rueckgabewert ist das Zeichen, jedoch auf jeden Fall
  54. *                 als Grossbuchstabe.
  55. *
  56. *****************************************************************************/
  57.  
  58. int ask_replace()
  59. {
  60.   /* *** interne Daten *** */
  61.   int antw; /* zum Einlesen eines Zeichens */
  62.  
  63.   print_stat(PROMPT_REPLYN);
  64.   do
  65.     antw = newwgetch(status); /* Zeichen vom Tastatur / Macro lesen */
  66.   while (!strchr ("jnJNyYAa",antw));
  67.   clear_stat();
  68.   if (strchr ("yY", antw)) /* Beantwortung mit Y(es) zulassen */
  69.     antw = 'J';
  70.   return(upcase(antw));
  71. }
  72.  
  73. /*****************************************************************************
  74. *
  75. *  Funktion       Buchstabe in Grossbuchstabe wandeln (upcase)
  76. *  --------
  77. *
  78. *  Parameter    : c         :
  79. *                   Typ          : unsigned char
  80. *                   Wertebereich : (char) 0 - (char) 255
  81. *                   Bedeutung    : Umzuwandelndes Zeichen
  82. *
  83. *  Ergebnis     :
  84. *                   Typ          : unsigned char
  85. *                   Wertebereich : (char) 0 - (char) 255
  86. *                   Bedeutung    : umgewandeltes Zeichen
  87. *
  88. *  Beschreibung : Falls das Zeichen ein Buchstabe ist, wird es in einen
  89. *                 Grossbuchstaben umgewandelt.
  90. *
  91. *****************************************************************************/
  92.  
  93. unsigned char upcase (c)        /* eee klappt nicht bei Umlauten */
  94. register unsigned char c;
  95. {
  96.   return (isalpha(c)?toupper(c):c);
  97. }
  98.  
  99. /*****************************************************************************
  100. *
  101. *  Funktion       Text in String ? (instr)
  102. *  --------
  103. *
  104. *  Parameter    : begriff   :
  105. *                   Typ          : char*
  106. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  107. *                   Bedeutung    : String, nach dem gesucht wird
  108. *
  109. *                 zeile     :
  110. *                   Typ          : char*
  111. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  112. *                   Bedeutung    : String, in dem gesucht wird.
  113. *
  114. *                 ignore    :
  115. *                   Typ          : int
  116. *                   Wertebereich : TRUE, FALSE
  117. *                   Bedeutung    : TRUE : Gross-/Kleinschreibung ignorieren
  118. *
  119. *                 word      :
  120. *                   Typ          : int
  121. *                   Wertebereich : TRUE, FALSE
  122. *                   Bedeutung    : TRUE : Nur ganze Woerter finden
  123. *
  124. *                 richtung  :
  125. *                   Typ          : int
  126. *                   Wertebereich : TRUE, FALSE
  127. *                   Bedeutung    : TRUE : Vorwaerts suchen
  128. *                                  FALSE: Rueckwaerts suchen
  129. *
  130. *  Ergebnis     :
  131. *                   Typ          : char*
  132. *                   Wertebereich : Pointer auf ASCII-Zeichen
  133. *                   Bedeutung    : NULL = nicht gefunden
  134. *                                  Sonst : Position des Suchstrings in
  135. *                                          aktueller Zeile
  136. *
  137. *  Beschreibung : Die uebergebene Zeile wird auf den uebergebenen Suchstring
  138. *                 begriff untersucht. Dabei wird, falls das ignore-Flag TRUE
  139. *                 ist, die Gross-/Kleinschreibung ignoriert.
  140. *                 Ist das Word-Flag gesetzt, so werden nur Suchbegriffe gefun-
  141. *                 den, die rechts und links entweder Zeilenanfang bzw. Zeilen-
  142. *                 ende oder einen Worttrenner haben.
  143. *
  144. *****************************************************************************/
  145.  
  146. char *instr(begriff,zeile,ignore,word,richtung)
  147. register char *begriff;
  148. char *zeile;
  149. int  ignore,word,richtung;
  150. {
  151.   /* *** interne Daten und Initialisierung *** */
  152.   register int  beg_sc,               /* Zwischenspeicher Cursorspalte  */
  153.         len=strlen(begriff),  /* Laenge des Suchbegriffs        */
  154.         index=0,              /* Index in aktuellen Suchbegriff */
  155.         fr_ret;               /* Rueckgabewert von fastright    */
  156.   register char *beg_start;           /* Position des Suchbegriffs in   */
  157.                       /* der Zeile (nur bei word)       */
  158.  
  159.   if (!word)    /* Es muss kein abgeschlossenes Wort gefunden werden */
  160.   {
  161.     do
  162.     {
  163.       if (ignore? /* Wird Gross-/Kleinschreibung ignoriert, dann upcase */
  164.       (upcase(*zeile) != upcase(begriff[index++])):(*zeile != begriff[index++]))
  165.       {
  166.     if (!fastleft(&zeile,index-richtung)) /* Nicht gefunden, ein Zeichen  */
  167.     {                                     /* weiter rechts/links mit der  */
  168.       index = 0;                          /* Suche starten. Zeile zuende, */
  169.       break;                              /* dann do-while abbrechen      */
  170.     }
  171.     index = 0;      /* Im Suchbegriff wieder vorne beginnen */
  172.     if (!richtung)  /* Falls rueckwaerts gesucht wird, nicht mehr nach */
  173.       continue;     /* rechts, da Position 0 getestet werden muss.     */
  174.       }
  175.       if(fr_ret = !fastright(&zeile,1)) /* dadurch steht man auch wenn gefunden */
  176.     break;/* wurde hinter dem Suchbegriff, ausser Suchbegriff am Zeilenende */
  177.     }while (index < len); /* Solange suchen, bis Suchbegriff gefunden wurde */
  178.     if (index == len)     /* Wenn Suchbegriff gefunden wurde: */
  179.     {                               /* Zum Anfang des Suchbegriffs gehen */
  180.       fastleft(&zeile,len-fr_ret);  /* Falls Suchbegriff am Zeilenende, klappte */
  181.       return (zeile);               /* fastright nicht, also 1 weniger nach links */
  182.     }
  183.     else                  /* Wurde Suchbegriff nicht gefunden, NULL zurueck */
  184.       return (NULL);
  185.   }
  186.   else          /* Es soll ein abgeschlossenes Wort gefunden werden */
  187.   {
  188.     while (1)
  189.     {
  190.       /* Durch rekursiven Aufruf Begriff zunaechst normal in der Zeile */
  191.       /* suchen. Wird er nicht gefunden, return(NULL), sonst testen,   */
  192.       /* ob Wortgrenzen vorhanden                                      */
  193.       if (beg_start = zeile = instr(begriff,zeile,ignore,FALSE,richtung))
  194.       {
  195.     beg_sc = akt_winp->screencol;
  196.     if ((!fastleft(&zeile,1) || wortende(*zeile))) /* Wortende oder */
  197.     {                                         /* Zeilenende links ? */
  198.       zeile = beg_start;
  199.       akt_winp->screencol = beg_sc;
  200.       fastright(&zeile,len - 1);   /* Zum Ende des Suchbegriffs gehen */
  201.       if (!fastright(&zeile,1) || wortende(*zeile)) /* Wenn hinter Such-   */
  202.       {                                             /* begriff Zeilenende, */
  203.         akt_winp->screencol = beg_sc;
  204.         return (beg_start);         /* dann auch Wortende, also gefunden ! */
  205.       }
  206.     }
  207.     akt_winp->screencol = beg_sc;   /* Cursorspalte restaurieren    */
  208.     zeile = beg_start;              /* Zeiger in Zeile restaurieren */
  209.     /* Suche ein Z. weiter rechts/links fortsetzen */
  210.     if(richtung ? !fastright(&zeile,1)
  211.             : !fastleft (&zeile,1))
  212.       return(NULL);          /* Zeilenende, nicht gefunden */
  213.       }
  214.       else
  215.     return (NULL); /* Begriff in aktueller Zeile nicht gefunden  */
  216.     } /* Falls kein Wortende gefunden, nach erneutem Vorkommen suchen */
  217.   }
  218. }
  219.  
  220. /*****************************************************************************
  221. *
  222. *  Funktion       Begriff im Text suchen (find)
  223. *  --------
  224. *
  225. *  Parameter    : begriff   :
  226. *                   Typ          : char*
  227. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  228. *                   Bedeutung    : Suchbegriff
  229. *
  230. *                 richtung  :
  231. *                   Typ          : int
  232. *                   Wertebereich : TRUE, FALSE
  233. *                   Bedeutung    : TRUE : vorwaerts , FALSE : rueckwaerts
  234. *
  235. *                 ignore    :
  236. *                   Typ          : int
  237. *                   Wertebereich : TRUE, FALSE
  238. *                   Bedeutung    : Gross-/Kleinschreibung ignorieren
  239. *
  240. *                 word      :
  241. *                   Typ          : int
  242. *                   Wertebereich : TRUE, FALSE
  243. *                   Bedeutung    : Nur ganze Woerter finden
  244. *
  245. *                 start_line:
  246. *                   Typ          : int
  247. *                   Wertebereich : 0-MAX_ANZ_LINES
  248. *                   Bedeutung    : Nummer der Zeile, in der die Suche
  249. *                                  gestartet wurde.
  250. *
  251. *                 start_col :
  252. *                   Typ          : int
  253. *                   Wertebereich : 0-MAXLENGTH
  254. *                   Bedeutung    : Nummer der Spalte, in der die Suche
  255. *                                  gestartet wurde.
  256. *
  257. *                 count     :
  258. *                   Typ          : int*
  259. *                   Wertebereich : Pointer auf Integer
  260. *                   Bedeutung    : Wenn die Zeile, in der die Suche begann,
  261. *                                  schon durchsucht wurde, ist *count 0,
  262. *                                  sonst 1.
  263. *
  264. *  Ergebnis     :
  265. *                   Typ          : int
  266. *                   Wertebereich : TRUE, FALSE
  267. *                   Bedeutung    : TRUE : begriff gefunden
  268. *                                  FALSE: begriff nicht gefunden
  269. *
  270. *  Beschreibung : Es wird ab der aktuellen Position im Text nach dem ueber-
  271. *                 gebenen Begriff gesucht. Dabei werden die Parameter richtung,
  272. *                 ignore und word beruecksichtigt. Kommt man in der Zeile hinter
  273. *                 der aktuellen an und count ist 0, so wird die Suche beendet.
  274. *                 Findet man den Suchbegriff in der Zeile, in der die Suche
  275. *                 gestartet wurde, hinter der Startspalte, so wird FALSE
  276. *                 zurueckgegeben.
  277. *                 Die Suche innerhalb einer Zeile wird durch die Funktion instr
  278. *                 durchgefuehrt. Dadurch ist die Suche innerhalb einer Zeile
  279. *                 unabhaengig vom Parameter richtung.
  280. *
  281. ******************************************************************************/
  282.  
  283. int find(begriff,richtung,ignore,word,start_line,start_col,count)
  284. register char *begriff;
  285. int  richtung,ignore,word,start_line,start_col,*count;
  286. {
  287.   /* *** interne Daten und Initialisierung *** */
  288.   register char *zeile;                       /* Zeiger in akt. Zeile    */
  289.   register int  blen = strlen(begriff),       /* Laenge des Suchbegriffs */
  290.         old_sc = akt_winp->screencol, /* Alte Cursorspalte       */
  291.         old_line=akt_winp->textline,  /* Alte Cursorzeile        */
  292.         nsl=start_line+2*richtung-1;  /* erste Zeile, die nicht  */
  293.                           /* zweimal durchsucht wer- */
  294.                           /* den darf.               */
  295.   int           fl;      /* Laenge der aktuellen Zeile im screencol-Mass */
  296.  
  297.   if (!start_line && !richtung)
  298.     nsl=akt_winp->maxline+1;
  299.   else
  300.     if (start_line == akt_winp->maxline && richtung)
  301.       nsl = -1;
  302.   print_stat(PROMPT_SEARCHING);
  303.  
  304.   /* Falls Cursor auf oder hinter dem Zeilenende steht und rueckwaerts */
  305.   /* gesucht werden soll, Cursor um die Laenge des Suchbegriffs vor    */
  306.   /* das Zeilenende setzen.                                            */
  307.   if(akt_winp->screencol >= (fl = fastll(akt_winp->alinep->text)) && !richtung)
  308.     akt_winp->screencol = fl - blen;  /* screencol kann zwar < 0 werden,    */
  309.                       /* da aber fastzeichen dann hinterher */
  310.   else                                /* &space liefert, ist das egal.      */
  311.     if(akt_winp->screencol < 0)
  312.     {
  313.       if(!up())
  314.     gotox(akt_winp->maxline);
  315.       akt_winp->screencol =  fl - blen;
  316.     }
  317.   do
  318.   {
  319.     /* bei vorwaerts suchen werden leere Zeilen uebersprungen,
  320.        bei rueckwaerts suchen zu kurze Zeilen */
  321.     if((zeile = fastzeichen(akt_winp->screencol)) != &space)
  322.     {
  323.       if(*zeile == '_' && zeile[1] == '' && zeile[2]) /* Falls aktuelles     */
  324.     zeile+=2; /* Zeichen unterstrichen ist, zeile auf Zeichen statt auf _ */
  325.       if (instr(begriff,zeile,ignore,word,richtung))     /* Zeile durchsuchen */
  326.     /* Wenn Teil der Zeile schonmal durchsucht, testen, ob gefundener Teil*/
  327.     /* im schon durchsuchten Teil liegt.                                  */
  328.     if(akt_winp->textline == start_line &&
  329.     (richtung ? akt_winp->screencol >= start_col
  330.           : akt_winp->screencol <= start_col) && !*count)
  331.       break; /* Wenn ja, ist Ergebnis ungueltig, abbrechen */
  332.     else
  333.     {
  334.       clear_stat();
  335.       return (TRUE);
  336.     }
  337.     }
  338.     /* Zur naechsten zu durchsuchenden Zeile gehen */
  339.     akt_winp->alinep = richtung?akt_winp->alinep->next:akt_winp->alinep->prev;
  340.     if((akt_winp->textline += 2*richtung-1) < 0)
  341.       akt_winp->textline = akt_winp->maxline + 1; /* alinep steht auf dummyp */
  342.     else
  343.       if(akt_winp->textline > akt_winp->maxline)
  344.     akt_winp->textline = -1;        /* alinep steht auf dummyp */
  345.  
  346.     /* Bei vorwaertssuchen ab erster Spalte beginnen, bei Rueckwaertssuchen */
  347.     /* blen Spalten vor Zeilenende, da Suchbegriff nicht spaeter anfangen   */
  348.     /* kann.                                                                */
  349.     akt_winp->screencol = richtung?0:fastll(akt_winp->alinep->text)-blen;
  350.   }while(akt_winp->textline != nsl || (*count)--); /* ganzen Text durchlaufen */
  351.   gotox (old_line);             /* falls nicht gefunden, an alte Position */
  352.   akt_winp->screencol = old_sc;
  353.   clear_stat();
  354.   return (FALSE);
  355. }
  356.  
  357. /*****************************************************************************
  358. *
  359. *  Funktion       In einem String enthaltene Zahl berechnen (str_to_num)
  360. *  --------
  361. *
  362. *  Parameter    : string    :
  363. *                   Typ          : char*
  364. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  365. *                   Bedeutung    : String, in dem die Zahl enthalten ist
  366. *
  367. *  Ergebnis     :
  368. *                   Typ          : int
  369. *                   Wertebereich : 0-MAXINT
  370. *                   Bedeutung    : Im String enthaltene Zahl als int
  371. *
  372. *  Beschreibung : Zuerst wird die erste im String vorkommende Ziffer gesucht.
  373. *                 Dann wird die Ziffer in einen Integer umgewandelt. Bei
  374. *                 jeder weiteren gefundenen Ziffer wird der bisherige Wert
  375. *                 mit 10 multipliziert und der Wert der gefundenen Ziffer
  376. *                 addiert. Sobald das Stringende oder keine Ziffer gefuden
  377. *                 wird, bricht die Funktion ab.
  378. *
  379. *****************************************************************************/
  380.  
  381. int str_to_num(string)
  382. register char *string;
  383. {
  384.   /* *** interne Daten *** */
  385.   register int hilf=0; /* vorlaeufiges Ergebnis */
  386.  
  387.   while (*string && (*string < '0' || *string > '9'))
  388.     string++;   /* erste Ziffer suchen */
  389.   if (!*string) /* Keine Ziffer gefunden, -1 zurueck */
  390.     return (-1);
  391.   while (isdigit(*string))
  392.     hilf = 10*hilf + *string++ - '0';
  393.   return (hilf);
  394. }
  395.  
  396. /*****************************************************************************
  397. *
  398. *  Funktion       Optionen in Werte wandeln (o_to_vals)
  399. *  --------
  400. *
  401. *  Parameter    : optionen  :
  402. *                   Typ          : char*
  403. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  404. *                   Bedeutung    : Auszuwertender String
  405. *
  406. *               : richtung  :
  407. *                   Typ          : int*
  408. *                   Wertebereich : Pointer auf Integer
  409. *                   Bedeutung    : TRUE:vorwaerts, FALSE:rueckwaerts
  410. *
  411. *               : anzahl    :
  412. *                   Typ          : int*
  413. *                   Wertebereich : Pointer auf integer
  414. *                   Bedeutung    : Anzahl der Wiederholungen
  415. *
  416. *               : ignore    :
  417. *                   Typ          : int*
  418. *                   Wertebereich : Pointer auf integer
  419. *                   Bedeutung    : Gross-/Kleinschreibung ignorieren
  420. *
  421. *               : word      :
  422. *                   Typ          : int*
  423. *                   Wertebereich : Pointer auf integer
  424. *                   Bedeutung    : Nur ganze Worte finden
  425. *
  426. *               : anf_ende  :
  427. *                   Typ          : int*
  428. *                   Wertebereich : Pointer auf Integer
  429. *                   Bedeutung    : Soll vom Anfang oder vom Ende gesucht/
  430. *                                  ersetzt werden ?
  431. *
  432. *  Beschreibung : Anhand des Optionenstrings werden die Parameter gesetzt.
  433. *                 anzahl wird ueber str_to_num ermittelt, alle anderen
  434. *                 ueber die Funktion strchr.
  435. *
  436. *****************************************************************************/
  437.  
  438. void o_to_vals(optionen,richtung,anzahl,ignore,word,anf_ende)
  439. char *optionen;
  440. int  *richtung,*anzahl,*ignore,*word,*anf_ende;
  441. {
  442.   /* Wenn der aktuelle Vorgang eine Wiederholung ist */
  443.   /* oder der User keine Anzahl angegeben hat, wird  */
  444.   /* die Anzahl auf 1 gesetzt.                       */
  445.   if (repeatflag || (*anzahl = str_to_num(optionen))==-1)
  446.     *anzahl = 1;
  447.  
  448.   *richtung = !strchr(optionen,'r') && !strchr(optionen,'R');
  449.   *ignore   =  strchr(optionen,'i') ||  strchr(optionen,'I');
  450.   *word     =  strchr(optionen,'w') ||  strchr(optionen,'W');
  451.   *anf_ende =  FALSE;         /* default: nicht von Anfang oder Ende */
  452.   if (strchr(optionen,'b') || strchr(optionen,'B'))
  453.   {
  454.     if(!repeatflag) /* bei repeat nicht mehr vom anfang an */
  455.     {
  456.       *anf_ende = TRUE;
  457.       gotox(0);                /* Zeile 0, Spalte 0 aufsuchen */
  458.       akt_winp->screencol = 0;
  459.     }
  460.     *richtung = 1; /* Bei Suchen vom anfang immer vorawerts */
  461.   }
  462.   else
  463.     if (strchr(optionen,'e') || strchr(optionen,'E'))
  464.     {
  465.       if(!repeatflag)
  466.       {
  467.     *anf_ende = TRUE;         /* letzte Zeile, letzte Spalte aufsuchen */
  468.     gotox(akt_winp->maxline);
  469.     akt_winp->screencol = fastll(akt_winp->alinep->text)-1;
  470.       }
  471.       *richtung = 0;      /* Wenn vom Ende aus gesucht werden soll, dann  */
  472.     }                     /* auf jeden Fall rueckwaerts.                  */
  473. }
  474.  
  475. /*****************************************************************************
  476. *
  477. *  Funktion       Letztes Suchen/Ersetzen wiederholen (do_repfr)
  478. *  --------
  479. *
  480. *  Beschreibung : Falls schon eine Suche bzw. Ersetzung stattgefunden hat,
  481. *                 wird diese mit den gleichen Optionen, jedoch anzahl=1
  482. *                 wiederholt.
  483. *
  484. *****************************************************************************/
  485.  
  486. void do_repfr()
  487. {
  488.   if (last_func != F_NONE)
  489.   {
  490.     repeatflag = TRUE;
  491.     if (last_func == F_FIND)
  492.       do_find();
  493.     else
  494.       do_replace();
  495.     repeatflag = FALSE;
  496.   }
  497. }
  498.  
  499. /*****************************************************************************
  500. *
  501. *  Funktion       Suchen ausfuehren (do_find)
  502. *  --------
  503. *
  504. *  Beschreibung : Falls die Funktion nicht durch do_repfr() aufgerunfen wurde,
  505. *                 werden Suchbegriff und Optionen eingelesen. Anschliessend
  506. *                 wird mit der Funktion o_to_vals der Optionenstring in die
  507. *                 Parameter zerteilt und anzahl mal find() aufgerufen.
  508. *
  509. *****************************************************************************/
  510.  
  511. void do_find()
  512. {
  513.   /* *** interne Daten und Initialisierung *** */
  514.   int          richtung,   /* Flag, ob vorawerts gesucht wird                */
  515.            anzahl,     /* Anzahl der Suchwiederholungen                  */
  516.            alt_anz,    /* Zwischenspeicher fuer Wiederholungszahl        */
  517.            ignore,     /* Flag, ob Gross-/Kleinschreibung ignoriert wird */
  518.            word,       /* Flag, ob nur ganze Woerter gefunden werden     */
  519.            anf_ende,   /* Flag, ob vom Anfang oder vom Ende gesucht wird */
  520.            count=1;    /* Zeigt an, ob die Zeile hinter der Anfangszeile */
  521.                /* schon einmal durchsucht wurde.                 */
  522.   register int slen,       /* Laenge des Suchbegriffs                        */
  523.            start_line, /* Zeile, in der die Suche begann                 */
  524.            start_col;  /* Spalte, in der die Suche begann                */
  525.   char         dummy[256]; /* String fuer zusammengeflickte Fehlermeldung    */
  526.  
  527.   if(akt_winp->maxline >= 0) /* Wenn Text leer, dann auch nicht suchen */
  528.   {
  529.     last_func = F_FIND;      /* Fuer do_repfr Funktionstyp merken */
  530.     if (!repeatflag)         /* Handelt es sich um eine Wiederholung, dann   */
  531.     {                        /* wird der Suchbegriff nicht erneut eingelesen */
  532.       print_stat(PROMPT_SEARCH);
  533.       read_stat(sbegriff,255,GS_ANY);
  534.       clear_stat();
  535.     }
  536.     if(slen = strlen(sbegriff)) /* Bei leerem Suchbegriff nichts unternehmen */
  537.     {
  538.       if (!repeatflag) /* Optionen nur einlesen, wenn es keine Wiederholung ist */
  539.       {
  540.     print_stat(PROMPT_FOPTIONS);
  541.     read_stat(optionen,255,GS_ANY);
  542.     clear_stat();
  543.       }
  544.       akt_winp->lastline = akt_winp->textline; /* Aktuelle Position als letzte */
  545.       akt_winp->lastcol = akt_winp->screencol; /* Position merken              */
  546.  
  547.       /* Optionen auswerten */
  548.       o_to_vals(optionen,&richtung,&anzahl,&ignore,&word,&anf_ende);
  549.  
  550.       start_line = akt_winp->textline;
  551.       if (!anf_ende) /* Wenn nicht vom Anfang oder vom Ende gesucht werden soll,*/
  552.     akt_winp->screencol += 2*richtung-1;      /* Dann von einer Pos. weiter */
  553.       start_col=akt_winp->screencol;              /* rechts/links suchen        */
  554.       check_buff();       /* Evtl. Puffer zurueck, da auch alinep->text wichtig */
  555.  
  556.       /* Wenn der Cursor beim Vorwaertssuchen am Zeilenende steht oder beim */
  557.       /* Rueckwaertssuchen am Zeilenanfang, dann wird die Nummer der Start- */
  558.       /* zeile und der Startspalte angepasst. */
  559.       if (richtung ? fastzeichen(start_col) == &space : akt_winp->screencol == -1)
  560.       {
  561.     if((start_line += 2*richtung-1) < 0)
  562.       start_line = akt_winp->maxline;
  563.     else
  564.       if(start_line > akt_winp->maxline)
  565.         start_line = 0;
  566.     start_col=richtung?0:MAXLENGTH - slen; /* Fall rueckwaerts suchen, dann */
  567.       }                                  /* Zeilenende als Suchbeginn markieren */
  568.       if ((alt_anz = anzahl) > 0)
  569.       {
  570.     /* Suchbegriff suchen bis nicht mehr zu finden oder gewuenschte Anzahl */
  571.     while (find(sbegriff,richtung,ignore,word,start_line,start_col,&count)
  572.           && --anzahl)
  573.       akt_winp->screencol += richtung ? slen : -1;    /* begriff skippen */
  574.     adapt_screen(sbegriff); /* anschliessend Bildschirm anpassen */
  575.     if (anzahl) /* Wurde nicht die geforderte Anzahl gefunden ? */
  576.     {
  577.       if (alt_anz == anzahl) /* Keinmal ? */
  578.       {
  579.         if (!anf_ende)
  580.           akt_winp->screencol--;
  581.         strcpy(dummy,PROMPT_NOTFOUND);
  582.       }
  583.       else
  584.       {
  585.         akt_winp->screencol -= richtung ? slen : -1; /* Skippen rueckgaengig machen */
  586.         sprintf (dummy,PROMPT_FOUNDN,alt_anz-anzahl);
  587.       }
  588.       pe_or(dummy);
  589.     }
  590.       }
  591.     }
  592.     setz_cursor(W_AKT);
  593.   }
  594.   else
  595.     print_err(PROMPT_FEMPTY);
  596. }
  597.  
  598. /*****************************************************************************
  599. *
  600. *  Funktion       Ersetzungsbegriff eintragen (trag_e_ein)
  601. *  --------
  602. *
  603. *  Parameter    : ebegriff  :
  604. *                   Typ          : char *
  605. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  606. *                   Bedeutung    : Einzutragender Begriff
  607. *
  608. *                 elen      :
  609. *                   Typ          : int
  610. *                   Wertebereich : 0 - MAX_INT
  611. *                   Bedeutung    : Laenge des Ersetzungsbegriffs
  612. *
  613. *  Beschreibung : Der uebergebene Ersetzungsbegriff wird mit der Funktion
  614. *                 enter_char() ab der aktuellen Position in den Text ein-
  615. *                 getragen. Dabei wird der Insert-Mode abgeschaltet.
  616. *
  617. *****************************************************************************/
  618.  
  619. void trag_e_ein(ebegriff,elen)
  620. register char *ebegriff;
  621. register int elen;
  622. {
  623.   /* *** interne Daten und Initialisierung *** */
  624.   register int i,                        /* Schleifenzaehler              */
  625.            oldi = akt_winp->insflag; /* Zwischenspeicher fuer insflag */
  626.  
  627.   akt_winp->insflag = FALSE;    /* damit enter_char Zeichen PUTtet */
  628.   for (i=0;i<elen;i++)
  629.     enter_char(*ebegriff++);
  630.   akt_winp->insflag = oldi;     /* Insert-Mode restaurieren */
  631. }
  632.  
  633. /*****************************************************************************
  634. *
  635. *  Funktion       Wort zum Blinken bringen (flash_word)
  636. *  --------
  637. *
  638. *  Parameter    : laenge    :
  639. *                   Typ          : int
  640. *                   Wertebereich : 0-MAXLENGTH
  641. *                   Bedeutung    : Laenge des zum Bilnek zu bringenden Worts
  642. *
  643. *  Beschreibung : Ab der aktuellen Cursorposition werden laenge Zeichen zum
  644. *                 blinken gebracht, d.h. mit dem Ersetzungsattribut.
  645. *                 versehen.
  646. *
  647. *****************************************************************************/
  648.  
  649. void flash_word(laenge)
  650. register int laenge;
  651. {
  652.   while (laenge--)
  653.     waddch(akt_winp->winp,winch(akt_winp->winp) | 256*ersetzaddr);
  654. }
  655.  
  656. /*****************************************************************************
  657. *
  658. *  Funktion       Wort "entblinken" (unflash_word)
  659. *  --------
  660. *
  661. *  Parameter    : laenge    :
  662. *                   Typ          : int
  663. *                   Wertebereich : 0-MAXLENGTH
  664. *                   Bedeutung    : Laenge des zu "entblinkenden" Wortes
  665. *
  666. *  Beschreibung : Ab der aktuellen Cursorposition wird bei laenge Zeichen
  667. *                 das Attribut fuer Blinken (ersatzaddr) geloescht.
  668. *
  669. *****************************************************************************/
  670.  
  671. void unflash_word(laenge)
  672. register int laenge;
  673. {
  674.   while (laenge--)
  675.     waddch(akt_winp->winp,winch(akt_winp->winp) & ~(256*ersetzaddr));
  676. }
  677.  
  678. /*****************************************************************************
  679. *
  680. *  Funktion       Ersetzen ausfuehren (do_replace)
  681. *  --------
  682. *
  683. *  Beschreibung : Falls die Funktion nicht von do_repfr aufgerufen wurde,
  684. *                 kann der Benutzer Such-, Ersetzungsbegriff und Optionen
  685. *                 eingeben. Dann wird ab der aktuellen Position aus der Such-
  686. *                 begriff gesucht und je nach Option mit oder ohne Abfrage
  687. *                 ersetzt. Die Suche kann vorwaerts und rueckwaerts, nur
  688. *                 nach ganzen worten oder unter Ignorierung der Gross-/Klein-
  689. *                 schreibnug durchgefuehrt werden. Zur Suche wird die Funktion
  690. *                 find() benutzt, um den Begriff zu ersetzen die Funktion
  691. *                 trag_e_ein().
  692. *
  693. *****************************************************************************/
  694.  
  695. void do_replace()
  696. {
  697.   /* *** interne Daten und Initialisierung *** */
  698.   int          richtung,    /* Flag, ob vorawerts gesucht wird                */
  699.            anzahl,      /* Anzahl der Ersetzungswiederholungen            */
  700.            ignore,      /* Flag, ob Gross-/Kleinschreibung ignoriert wird */
  701.            word,        /* Flag, ob nur ganze Woerter gefunden werden     */
  702.            alt_anz,     /* Zwischenspeicher fuer Wiederholungszahl        */
  703.            diff,
  704.            dl,
  705.            globalflag;
  706.   register int oldu = akt_winp->underflag, /* Zwischenspeicher */
  707.            slen,        /* Laenge des Suchbegriffs                        */
  708.            elen,        /* Laenge des Ersetzungsbegriffs                  */
  709.            ulflag,      /* Flag, ob Ersetzungsbegriff nach aktuellem      */
  710.                 /* Modus oder nach dem ersten Zeichen des gefun-  */
  711.                 /* denen Suchbegriffs unterstrichen werden soll   */
  712.            allflag;     /* Flag, ob alle vorkommenden Suchstrings ersetzt */
  713.                 /* werden sollen.                                 */
  714.   int          ret,         /* Rueckgabewert von ask_replace                  */
  715.            start_line=akt_winp->textline, /* Suchstart Zeile              */
  716.            start_col=akt_winp->screencol, /* Suchstart Spalte             */
  717.            count=1;     /* Zeigt an, ob die Zeile hinter der Anfangszeile */
  718.                 /* schon einmal durchsucht wurde.                 */
  719.   char         dummy[256];
  720.  
  721.   if(akt_winp->maxline >= 0) /* Wenn Text leer, nichts suchen */
  722.   {
  723.     last_func = F_REPLACE; /* Funktionstyp fuer evtl. Wiederholung merken */
  724.     check_buff(); /* Evtl. Puffer zurueckschreiben, da alinep->text gebraucht */
  725.     if (!repeatflag)       /* wird. */
  726.     {                      /* Bei Wiederholung keinen neuen Suchbegriff,  */
  727.       print_stat(PROMPT_SEARCH); /* keinen neuen Ersetzungsbegriff und */
  728.       read_stat(sbegriff,255,GS_ANY); /* keine neuen Optionen einlesen    */
  729.       clear_stat();
  730.       if(!sbegriff[0])    /* falls leer, raus */
  731.       {
  732.     setz_cursor(W_AKT);
  733.     return;
  734.       }
  735.       print_stat(PROMPT_REPLACE);
  736.       read_stat(ebegriff,255,GS_ANY);
  737.       clear_stat();
  738.       print_stat(PROMPT_ROPTIONS);
  739.       read_stat(optionen,255,GS_ANY);
  740.       clear_stat();
  741.     }
  742.     /* Laengendifferenz zwischen Such- und Ersetzungsbegriff berechnen */
  743.     diff = (elen = strlen(ebegriff))-(slen = strlen(sbegriff));
  744.     akt_winp->lastline = akt_winp->textline; /* aktuelle Position als  */
  745.     akt_winp->lastcol = akt_winp->screencol; /* letzte Position merken */
  746.  
  747.     /* Optionenstring auswerten */
  748.     o_to_vals(optionen,&richtung,&anzahl,&ignore,&word,&dl); /* dl ist DUMMY */
  749.     alt_anz = anzahl;
  750.     globalflag = strchr(optionen,'g') || strchr(optionen,'G');
  751.     allflag = strchr(optionen,'a') || strchr(optionen,'A'); /* alle? */
  752.     ulflag = strchr(optionen,'u') || strchr(optionen,'U'); /* unterstr. nach modus?*/
  753.  
  754.     /* Falls Cursor hinter Zeilenende oder vor Zeilenanfang steht, */
  755.     /* naechste Suchposition als Startposition eintragen.          */
  756.     if (richtung && fastzeichen(start_col) == &space)
  757.     {
  758.       if((start_line += 2*richtung-1) < 0) /* Bei Textanfang oder */
  759.     start_line = akt_winp->maxline;    /* Textende wraparound */
  760.       else
  761.     if(start_line > akt_winp->maxline)
  762.       start_line = 0;
  763.       start_col=richtung?0:MAXLENGTH - slen; /* Fall rueckwaerts suchen, dann Zeilenende als Suchbeginn markieren */
  764.     }
  765.  
  766.     /* Suchbegriff entweder anzahl mal oder bei gesetztem allflag so oft */
  767.     /* es geht suchen und ersetzen.                                      */
  768.     while ((allflag || anzahl--) && find(sbegriff,richtung,ignore,word,start_line,start_col,&count))
  769.     {
  770.       if (!globalflag)  /* muss Abfrage vorgenommen werden ? */
  771.       {
  772.     adapt_screen(sbegriff); /* Ja, dann Bildschirm anpassen */
  773.     flash_word(slen);       /* Suchbegriff highlighten */
  774.     setz_cursor(W_AKT);          /* und refreshen */
  775.     unflash_word(slen);     /* Highlight aus, aber noch kein refresh */
  776.     if((ret = ask_replace()) != 'J') /* soll nicht ersetzt werden ? */
  777.     {
  778.       if(ret == 'A')    /* Abbruch? */
  779.       {
  780.         anzahl = -1;    /* Meldung am Ende unterdruecken */
  781.         break;
  782.       }
  783.       akt_winp->screencol+=slen; /* Suchbegriff skippen */
  784.       wrefresh(akt_winp->winp);  /* Fenster refreshen   */
  785.       continue;
  786.     }
  787.       }
  788.       if(fastll(akt_winp->alinep->text) + diff > MAXLENGTH)
  789.     print_err(PROMPT_ERREPLACE);
  790.       else
  791.       {
  792.     /* falls erstes Zeichen des Wortes unterstrichen, wird gesamtes Wort
  793.        unterstrichen, wenn ulflag = FALSE, sonst wird je nach underline-
  794.        modus unterstrichen */
  795.     if(!ulflag)
  796.       if(ul_char())
  797.         akt_winp->underflag = TRUE;
  798.       else
  799.         akt_winp->underflag = FALSE;
  800.     mdelete(slen);
  801.     insert(elen); /* Platz fuer neuen (weil evtl. underlined) */
  802.     trag_e_ein(ebegriff,elen); /* Ersetzungsbegriff eintragen */
  803.     check_buff(); /* Puffer zurueckschreiben, da alinep->text gebraucht */
  804.       }
  805.       if(!globalflag) /* Wenn Abgefragt wurde, dann Bildschirm */
  806.       {               /* korrigieren */
  807.     lineout(akt_winp->textline - akt_winp->ws_line);
  808.     wrefresh(akt_winp->winp); /* veraenderte Zeile restaurieren */
  809.       }
  810.     } /* of while */
  811.  
  812.     /* Wenn nicht alle vorkommenden Suchbegriffe gefunden werden sollten */
  813.     /* und nicht abgebrochen wurde, testen ob alle gewuenschten Er-      */
  814.     /* setzungen durchgefuehrt werden konnten.                           */
  815.     if (!allflag && anzahl != -1)
  816.     {
  817.       if (alt_anz-1 == anzahl)
  818.     strcpy(dummy,PROMPT_NOTFOUND);
  819.       else
  820.     sprintf (dummy,PROMPT_FOUNDN,alt_anz-anzahl-1);
  821.       print_err(dummy);
  822.     }
  823.     if (globalflag) /* Wenn keine Abfrage stattfand, dann jetzt Bildschirm */
  824.       adapt_screen(sbegriff); /* anpassen */
  825.     show_win(W_AKT);         /* eee evtl. show_win zuviel, wenn adapt_screen */
  826.   }                     /* schon show_win() gemacht hatte               */
  827.   else
  828.     print_err(PROMPT_REMPTY);
  829.   akt_winp->underflag = oldu; /* underflag restaurieren */
  830. }
  831.